package com.cornerstone.tcmsmap {
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.external.*;
	import flash.display.LoaderInfo;
	import com.cornerstone.tcmsmap.ModeChangedEvent;
	import com.cornerstone.tcmsmap.DeleteWorkshopEvent;
	import fl.controls.*
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.PerspectiveProjection;
	import flash.net.URLRequest;
	import flash.text.TextFieldAutoSize;
	import flash.utils.Dictionary;
	import flash.globalization.DateTimeFormatter;
	
	/**
	 * ...
	 * @author Jiang Hongfei <jianghongfei@gmail.com>
	 */
	[Frame(factoryClass="com.cornerstone.tcmsmap.Preloader")]
	
	public class Main extends Sprite {
		//{ static
		public static var hoverBackgroundColor:uint;
		public static var hoverForegroundColor:uint;
		public static var idealForegroundColor:uint;
		public static var busyForegroundColor:uint;
		public static var tooltipBackgroundColor:uint;
		public static var tooltipBorderColor:uint;
		public static var tooltipForegroundColor:String;
		//}		
		
		//{ state
		private var _isInEditMode:Boolean = false;
		private var _targetURL:String;
		private var _resourceURL:String;
		private var _images:Dictionary = new Dictionary();
		
		private var _workshops:Vector.<Workshop>;
		//}
		
		//{ assets
		//}
		
		//{ controls
		private var _bg:Sprite;
		private var _content:Sprite;
		
		//}
		
		public function Main():void {
			if (stage)
				init();
			else
				addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		//{ getter & setter
		
		public function get isInEditMode():Boolean {
			return _isInEditMode;
		}
		
		public function set isInEditMode(value:Boolean):void {
			_isInEditMode = value;

			dispatchEvent(new ModeChangedEvent(ModeChangedEvent.MODE_CHANGED, value));
		}
		
		public function get targetURL():String 
		{
			return _targetURL;
		}
		
		public function set targetURL(value:String):void 
		{
			_targetURL = value;
		}
		
		public function get resourceURL():String 
		{
			return _resourceURL;
		}
		
		public function set resourceURL(value:String):void 
		{
			_resourceURL = value;
		}
		
		public function get images():Dictionary 
		{
			return _images;
		}
		
		public function set images(value:Dictionary):void 
		{
			_images = value;
		}
		
		//}
		
		private function init(e:Event = null):void {
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			ExternalInterface.addCallback("loadWorkShops", loadWorkShops);
			ExternalInterface.addCallback("getPositions", getPositions);
			ExternalInterface.addCallback("addWorkshop", addWorkshop);
			ExternalInterface.addCallback("deleteWorkshop", deleteWorkshop);
			ExternalInterface.addCallback("updateWorkshop", updateWorkshop);

			_bg = new Sprite();
			this.addChild(_bg);

			_content = new Sprite();
			this.addChild(_content);
			
			loadData();
		}
		
		//{ event handler
		
		private function bgLoadComplete(e:Event):void {
			var li:LoaderInfo = e.currentTarget as LoaderInfo;
			
			var _tempbg:DisplayObject = li.content;
			_bg.addChild(_tempbg);
			_tempbg.height = this.stage.stageWidth / _tempbg.width * _tempbg.height;
			_tempbg.width = this.stage.stageWidth;
			
			ExternalInterface.call("changeSWFHeight", _tempbg.height);
		}
		
		private function swapToTop(event:MouseEvent):void {
			_content.setChildIndex(event.currentTarget as Workshop, _content.numChildren - 1);
		}
		//}
		
		//{ methods
		
		public function url(name:String):String {
			return resourceURL + "/" + name;
		}
		
		private function loadData():void {
			// expose 'loadWorkShops' to javascript			
			isInEditMode = (this.loaderInfo.parameters.isInEditMode === "true");
			targetURL = (this.loaderInfo.parameters.targetURL);
			
			if (targetURL === null || targetURL.length === 0) {
				ExternalInterface.call('alert', "'targetURL' is invalid");
				return;
			}
			
			resourceURL = (this.loaderInfo.parameters.resourceURL);
			
			if (resourceURL === null || resourceURL.length === 0) {
				ExternalInterface.call('alert', "'resourceURL' is invalid");
				return;
			}
			
			try {
				hoverBackgroundColor = hex2ARGB(this.loaderInfo.parameters.hoverBackgroundColor);
			} catch (e:Error) {
				ExternalInterface.call('alert', "'hoverBackgroundColor' " + e.message);
				return;
			}
			
			try {
				hoverForegroundColor = hex2ARGB(this.loaderInfo.parameters.hoverForegroundColor);
			} catch (e:Error) {
				ExternalInterface.call('alert', "'hoverForegroundColor' " + e.message);
				return;
			}
			
			try {
				idealForegroundColor = hex2ARGB(this.loaderInfo.parameters.idealForegroundColor);
			} catch (e:Error) {
				ExternalInterface.call('alert', "'idealForeGroundColor' " + e.message);
				return;
			}
			
			try {
				busyForegroundColor = hex2ARGB(this.loaderInfo.parameters.busyForegroundColor);
			} catch (e:Error) {
				ExternalInterface.call('alert', "'busyForeGroundColor' " + e.message);
				return;
			}
			
			try {
				tooltipBackgroundColor = hex2ARGB(this.loaderInfo.parameters.tooltipBackgroundColor);
			} catch (e:Error) {
				ExternalInterface.call('alert', "'tooltipBackgroundColor' " + e.message);
				return;
			}
			
			try {
				tooltipBorderColor = hex2ARGB(this.loaderInfo.parameters.tooltipBorderColor);
			} catch (e:Error) {
				ExternalInterface.call('alert', "'tooltipBorderColor' " + e.message);
				return;
			}
			
			//try {
				tooltipForegroundColor = this.loaderInfo.parameters.tooltipForegroundColor;
			//} catch (e:Error) {
				//ExternalInterface.call('alert', "'tooltipForegroundColor' " + e.message);
				//return;
			//}

			var bgloader:Loader = new Loader();
			bgloader.contentLoaderInfo.addEventListener(Event.COMPLETE, bgLoadComplete);
			bgloader.load(new URLRequest(url("bg.png")));
			
			// call 'loaded' method in javascript, in which loadWorkShops method of swf object is called
			ExternalInterface.call("loaded");
		}
		
		private function deleteWorkshop(id:String):void 
		{	
			var index:int = 0;
			for each (var ws:Workshop in _workshops) 
			{
				if (ws.id === id) {
					_content.removeChild(ws);
					_workshops.splice(index, 1);
					
					break;
				}
				index++;
			}
		}
		
		public function loadWorkShops(raw:String):void {
			// clear content
			while (_content.numChildren > 0) {
				_content.removeChildAt(0);
			}
			
			_workshops = new Vector.<Workshop>();
			var items:Array = JSON.parse(raw) as Array;
			
			try {
				for each (var o:Object in items) {
					var ws:Workshop = new Workshop(this);
					_content.addChild(ws);
					
					ws.id = o.ID;
					ws.shopName = o.ShopName;
					ws.xposition = o.Xposition;
					ws.yposition = o.Yposition
					ws.status = o.Status;
					ws.icon = (o.Icon === "") ? 'ICON_00.png' : o.Icon;
					
					if (o.Task != null) {
						ws.tip = "<div>"
							   + "<strong>任务名称：</strong>" + o.Task.Name 
							   + "<br/><strong>产品名称：</strong>" + o.Task.ProductName 
							   + "<br/><strong>开始时间：</strong>" + msjsonDateFormatter(o.Task.StartTime) 
							   + "<br/><strong>截至时间：</strong>" + msjsonDateFormatter(o.Task.EndTime)
							   + "<br/><strong>主要危险品名称：</strong>" + o.Task.DangerousProducts
							   + "<br/><strong>在制量：</strong>" + o.Task.InPopulating
							   + "<br/><strong>危险工序：</strong>" + o.Task.DangerousProcedure
							   + "<br/><strong>带班长：</strong>" + o.Task.TeamLeader
							   + "<br/><strong>班组联系电话：</strong>" + o.Task.TeamTel
							   + "</div>";
					}
					
					ws.addEventListener(MouseEvent.MOUSE_OVER, swapToTop);
					ws.addEventListener(DeleteWorkshopEvent.DELETE, function(event:DeleteWorkshopEvent):void {
						ExternalInterface.call("deleteWorkshop", event.workshop.id, event.workshop.shopName);
					});
					
					ws.addEventListener(EditWorkshopEvent.EDIT, function(event:EditWorkshopEvent):void {
						ExternalInterface.call("editWorkshop", event.workshop.id, event.workshop.shopName, event.workshop.icon, event.workshop.status !== 2);
					});
					var loader:Loader = null;
					if (images.hasOwnProperty(ws.icon)) {
						loader = images[ws.icon];
					} else {
						loader = new Loader();
						images[ws.icon] = loader;
					}
					
					if (loader.contentLoaderInfo.content === null) {
						loader.contentLoaderInfo.addEventListener(Event.COMPLETE, ws.loadComplete);
						loader.load(new URLRequest(url(ws.icon)));
					} else {
						ws.setupBG(loader.content);
					}					

					_workshops.push(ws);
				}
			} catch (err:Error) {
				ExternalInterface.call('alert', err.message);
			}
		}

		private function msjsonDateFormatter(value:String):String {
			var newdate:Date = new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10));
			var dtf:DateTimeFormatter = new DateTimeFormatter("zh-Hans");
			dtf.setDateTimePattern("yyyy-MM-dd HH:mm:ss");
			return dtf.format(newdate); 
	    }
		
		public function getPositions():Array {
			var array:Array = new Array();
			for each (var item:Workshop in _workshops) 
			{
				var o:Object = new Object;
				o.ID = item.id;
				o.ShopName = item.shopName;
				o.Xposition = item.xposition;
				o.Yposition = item.yposition;
				o.Icon = item.icon;
				o.Status = item.status;
				
				array.push(o);
			}
			
			return array;
		}
		
		public function addWorkshop(shopName:String, icon:String, is_available:Boolean, x:int, y:int):void {
			var ws:Workshop = new Workshop(this);
			ws.id = GUID.create();
			ws.shopName = shopName;
			ws.xposition = x;
			ws.yposition = y;
			//ws.remark = remark;
			ws.icon = icon;
			ws.status = is_available ? 0 : 3;
			
			var loader:Loader = null;
			if (images.hasOwnProperty(ws.icon)) {
				loader = images[ws.icon];
			} else {
				loader = new Loader();
				images[ws.icon] = loader;
			}
			
			if (loader.contentLoaderInfo.content === null) {
				loader.contentLoaderInfo.addEventListener(Event.COMPLETE, ws.loadComplete);
				loader.load(new URLRequest(url(ws.icon)));
			} else {
				ws.setupBG(loader.content);
			}
					
			_content.addChild(ws);
			_workshops.push(ws);
		}
		
		public function updateWorkshop(id:String, shopName:String, icon:String, is_available:Boolean):void {
			for each (var ws:Workshop in _workshops) 
			{
				if (ws.id === id) {
					ws.shopName = shopName;
					ws.icon = icon;
					
					var loader:Loader = null;
					if (images.hasOwnProperty(ws.icon)) {
						loader = images[ws.icon];
					} else {
						loader = new Loader();
						images[ws.icon] = loader;
					}
					
					if (loader.contentLoaderInfo.content === null) {
						loader.contentLoaderInfo.addEventListener(Event.COMPLETE, ws.loadComplete);
						loader.load(new URLRequest(url(ws.icon)));
					} else {
						ws.updateBG(loader.content);
					}
					
					ws.status = is_available ? 0 : 2;
					return;
				}
			}
		}
		
		public function hex2ARGB(hex:String):uint {
			if (hex == null || hex.length != 7) {
				throw Error('Given hex string is invalid');
			}
			if (hex.indexOf("#") != -1) {
				hex = "0x" + hex.split("#").join("");
			}
			
			var hexValue:uint = parseInt(hex, 16);
			if(!isNaN(hexValue))
			{
			   return hexValue;
			}
			
			throw Error('Fail to parse given hex string');
		}
		//}
	}

}